#include "stdafx.h"
#include <windows.h>
#define _CRT_SECURE_NO_DEPRECATE
#pragma comment(lib, "glut32.lib") 
#pragma comment(lib, "glew32.lib") 
#pragma comment(lib, "openGL32.lib")

#include "../volumeEngineCore/volumeEngineCoreInterface.h"

volumeEngineCoreInterface* pRenderer = 0;
//virtual trackBall
trackBallInteraction* pTrackBall = 0;
gluiApp *AppUI;


//unsigned char *buffer = (unsigned char *)malloc(sizeof(unsigned int)*512*512);
parameterViewing pView;
parameterShading pShading;

void drawCubes(float x, float y, float z)
{
	glTranslatef(-x/2, -y/2, -z/2);

	glBegin(GL_QUADS);
	/* Back side */
	glNormal3f(0.0, 0.0, -1.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(0.0, y, 0.0);
	glVertex3f(x, y, 0.0);
	glVertex3f(x, 0.0, 0.0);

	/* Front side */
	glNormal3f(0.0, 0.0, 1.0);
	glVertex3f(0.0, 0.0, z);
	glVertex3f(x, 0.0, z);
	glVertex3f(x, y, z);
	glVertex3f(0.0, y, z);

	/* Top side */
	glNormal3f(0.0, 1.0, 0.0);
	glVertex3f(0.0, y, 0.0);
	glVertex3f(0.0, y, z);
    glVertex3f(x, y, z);
	glVertex3f(x, y, 0.0);

	/* Bottom side */
	glNormal3f(0.0, -1.0, 0.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(x, 0.0, 0.0);
	glVertex3f(x, 0.0, z);
	glVertex3f(0.0, 0.0, z);

	/* Left side */
	glNormal3f(-1.0, 0.0, 0.0);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(0.0, 0.0, z);
	glVertex3f(0.0, y, z);
	glVertex3f(0.0, y, 0.0);

	/* Right side */
	glNormal3f(1.0, 0.0, 0.0);
	glVertex3f(x, 0.0, 0.0);
	glVertex3f(x, y, 0.0);
	glVertex3f(x, y, z);
	glVertex3f(x, 0.0, z);
	glEnd();
	glTranslatef(x/2, y/2, z/2);
	
}
void display()
{
	//view transformation
	pView.rotateMatrix = pTrackBall->GetRotationMatrixPointer();
	pView.posVec = pTrackBall->GetTranslationVectorPointer();

	pRenderer->SetViewingParameters(pView);
	//pRenderer->SetShadingParameters(pShading);

	pRenderer->Render();
	
	glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
	drawCubes(1,1,1);

	glutSwapBuffers();
	
}

void idle(void)                                 
{
	glutSetWindow(AppUI->getWindowID());
	glutPostRedisplay();
}

void reshape (int w, int h)
{

}

void keyboard(unsigned char key, int x, int y)  
{
		
}

void mouse(int button, int state, int ix, int iy) 
//state GLUT_DOWN GLUT_UP
{
	float x = float(ix)/float(AppUI->getWidth());
	float y = float(iy)/float(AppUI->getHeight());
	
	if(button == GLUT_LEFT_BUTTON )
	{
		if(state == GLUT_DOWN)
			pTrackBall->OnLeftButtonDown(x, y);
		else
			pTrackBall->OnLeftButtonUp(x, y);

	}
	else if(button == GLUT_RIGHT_BUTTON)
	{
		if(state == GLUT_DOWN)
			pTrackBall->OnRightButtonDown(x, y);
		else
			pTrackBall->OnRightButtonUp(x, y);
	}
	else if(button == GLUT_MIDDLE_BUTTON)
	{
		if(state == GLUT_DOWN)
			pTrackBall->OnMiddleButtonDown(x, y);
		else
			pTrackBall->OnMiddleButtonUp(x, y);
	}
	 
  
}
void move(int x, int y)                         
{
	pTrackBall->OnMouseMove(float(x)/float(AppUI->getWidth()), float(y)/float(AppUI->getHeight()));

	glutPostRedisplay(); 

}
void init_gl()
{
    glewInit();
    if (!glewIsSupported( "GL_VERSION_2_0 GL_EXT_framebuffer_object" 
        )) {
        printf( "Required extensions not supported.\n");
        exit(-1);
    }

	pRenderer->InitEngine(AppUI->getWidth(), AppUI->getHeight());


	pTrackBall = new trackBallInteraction();


}

void cleanUp();

//DeleteRendererInstance deleteRenderer;
int _tmain(int argc, char* argv[])
{
	AppUI = new gluiApp(800,800);

	glutInit(&argc, argv);
	glutInitWindowSize(AppUI->getWidth(), AppUI->getHeight());

	glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB | GLUT_STENCIL);

	int window_id = glutCreateWindow("SimpleGL");

	//=====================
	//load the dll
#ifdef WIN32
	HINSTANCE hdll = NULL;
	typedef  volumeEngineCoreInterface* (*CreateRendererInstance)();

	hdll = LoadLibrary(("CUDAVolumeRenderer.dll") );
	CreateRendererInstance createRenderer;
	createRenderer = reinterpret_cast<CreateRendererInstance>( 
					GetProcAddress(hdll, ("CreateRendererInstance") ) );
	

	pRenderer = createRenderer();

#else

#endif
	//=====================
	init_gl();

	glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutMouseFunc(mouse);
	glutMotionFunc(move);
	glutIdleFunc(idle);


	AppUI->createUI();
	GLUI *glui = AppUI->glui  ;

	AppUI->setidle(idle);
	AppUI->setWindowID(window_id);



	AppUI->addSpinner("lightX", -2.0, 2.0, 0.9);
	AppUI->addSpinner("lightY", 0.0, 6.0, 2.2);
	AppUI->addSpinner("lightZ", -3.0, 3.0, 3.0);

	AppUI->addSpinner("polygonModel",-1, 1, 0);
	AppUI->addSpinner("lightOnOff",-1, 1, 0);
	AppUI->addSpinner("lightIntensity",0, 20, 0);
	AppUI->addSpinner("camera",-1, 1, 0);
	AppUI->addSpinner("wall", -4,4,4);

	AppUI->addSpinner("localframe",0,3,0);

	glui->add_column();	
	GLUI_Panel* SSAO = new GLUI_Panel( glui, "SSAO" );
	AppUI->currentPanel(SSAO);
	AppUI->addSpinner("totStrength",0,4,2.0);
	AppUI->addSpinner("strength",0,0.4,0.07);
	AppUI->addSpinner("offset",1,40,18.0);
	AppUI->addSpinner("falloff",0,0.1,0.0002);
	AppUI->addSpinner("rad",0,0.4,0.006);
	AppUI->addSpinner("offsetS",0,0.8,0.0);
	AppUI->addSpinner("useSfunc",0,1,1);

	atexit(cleanUp);
	//cleanUp();
	glutMainLoop();



	return 0;
}

void cleanUp()
{
	pRenderer->destroyObject();
}	
